#pragma once

/* 只是标记 */
#define ATOM
/* 原子操作 */

/* 定义内存序 */
#define __ATM_RELAX				__ATOMIC_RELAXED
/* WMO为主，全存储序不需要 */
#ifndef HDEF_WEAK_MEMORY_ORDER
	#define __ATM_RELEASE			__ATOMIC_RELAXED
	#define __ATM_ACQUIRE			__ATOMIC_RELAXED
	#define __ATM_ACQREL			__ATOMIC_RELAXED
#else
	#define __ATM_RELEASE			__ATOMIC_RELEASE
	#define __ATM_ACQUIRE			__ATOMIC_ACQUIRE
	#define __ATM_ACQREL			__ATOMIC_ACQ_REL
#endif

#ifdef HDEF_ARCH_X86
/* 可以启用lock elision */
#define __ATM_EXTRA_FLAG			__ATOMIC_HLE_ACQUIRE
#else
#define __ATM_EXTRA_FLAG			0
#endif

#define atm_ld(ptr)				__atomic_load_n(ptr, __ATM_RELAX)
#define atm_ldacq(ptr)				__atomic_load_n(ptr, __ATM_ACQUIRE)

#define atm_st(ptr, val)			__atomic_store_n(ptr, val, __ATM_RELAX)
#define atm_strel(ptr, val)			__atomic_store_n(ptr, val, __ATM_RELEASE)

/* 强cas, 不会失败 */
/* Built-in Function: bool __atomic_compare_exchange_n (type *ptr, type *expected, type desired,
	bool weak, int success_memorder, int failure_memorder) */
#define cas_s(ptr, expected, desired)				\
	__atomic_compare_exchange_n(ptr, expected, desired, 0, __ATM_RELAX, __ATM_RELAX)
#define cas_acq_s(ptr, expected, desired)			\
	__atomic_compare_exchange_n(ptr, expected, desired, 0, __ATM_ACQUIRE, __ATM_RELAX)
#define cas_rel_s(ptr, expected, desired)			\
	__atomic_compare_exchange_n(ptr, expected, desired, 0, __ATM_RELEASE, __ATM_RELAX)
#define cas_acqrel_s(ptr, expected, desired)			\
	__atomic_compare_exchange_n(ptr, expected, desired, 0, __ATM_ACQREL, __ATM_RELAX)

/* 弱cas, 可能会失败 */
#define cas(ptr, expected, desired)				\
	__atomic_compare_exchange_n(ptr, expected, desired, 1, __ATM_RELAX, __ATM_RELAX)
#define cas_acq(ptr, expected, desired)				\
	__atomic_compare_exchange_n(ptr, expected, desired, 1, __ATM_ACQUIRE, __ATM_RELAX)
#define cas_rel(ptr, expected, desired)				\
	__atomic_compare_exchange_n(ptr, expected, desired, 1, __ATM_RELEASE, __ATM_RELAX)
#define cas_acqrel(ptr, expected, desired)			\
	__atomic_compare_exchange_n(ptr, expected, desired, 1, __ATM_ACQREL, __ATM_RELAX)

/* 原子交换 */
#define swp(ptr, val)				__atomic_exchange_n(ptr, val, __ATM_RELAX)
#define swp_acq(ptr, val)			__atomic_exchange_n(ptr, val, __ATM_ACQUIRE)
#define swp_rel(ptr, val)			__atomic_exchange_n(ptr, val, __ATM_RELEASE)
#define swp_acqrel(ptr, val)			__atomic_exchange_n(ptr, val, __ATM_ACQREL)
#define swp_seqcst(ptr, val)			__atomic_exchange_n(ptr, val, __ATOMIC_SEQ_CST)

/* 原子加 */
#define faa(ptr, val)				__atomic_fetch_add(ptr, val, __ATM_RELAX)
#define faa_acq(ptr, val)			__atomic_fetch_add(ptr, val, __ATM_ACQUIRE)
#define faa_rel(ptr, val)			__atomic_fetch_add(ptr, val, __ATM_RELEASE)
#define faa_acqrel(ptr, val)			__atomic_fetch_add(ptr, val, __ATM_ACQREL)

/* 原子减 */
#define fas(ptr, val)				__atomic_fetch_sub(ptr, val, __ATM_RELAX)
#define fas_acq(ptr, val)			__atomic_fetch_sub(ptr, val, __ATM_ACQUIRE)
#define fas_rel(ptr, val)			__atomic_fetch_sub(ptr, val, __ATM_RELEASE)
#define fas_acqrel(ptr, val)			__atomic_fetch_sub(ptr, val, __ATM_ACQREL)


/* 与或非 */
#define __ATOMIC_BITOPS2(bitop, ptr, val, order)\
	__atomic_fetch_##bitop (ptr, val, order)

#define atm_bitops(bitop, ptr, val)		__ATOMIC_BITOPS2(bitop, ptr, val, __ATM_RELAX)
#define atm_bitops_acq(bitop, ptr, val)		__ATOMIC_BITOPS2(bitop, ptr, val, __ATM_ACQUIRE)
#define atm_bitops_rel(bitop, ptr, val)		__ATOMIC_BITOPS2(bitop, ptr, val, __ATM_RELEASE)

/* 还有额外的功能 */
// Built-in Function: type __atomic_xor_fetch (type *ptr, type val, int memorder)
// Built-in Function: type __atomic_or_fetch (type *ptr, type val, int memorder)
// Built-in Function: type __atomic_nand_fetch (type *ptr, type val, int memorder)
// Built-in Function: void __atomic_clear (bool *ptr, int memorder)
